#include<iostream>
#include<string>
#include<cerrno>
#include<cstring>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include"Log.hpp"
#include"nocopy.hpp"
#include<Comm.hpp>
using namespace std;

const static int default_backlog = 5;
class TcpServer:public nocopy
{
    public:
    TcpServer(uint16_t port) : _port(port){}
    void Init(){
        //创建套接字
        _listensock=socket(AF_INET,SOCK_STREAM,0);
        if(_listensock<0){
            lg.LogMessage(Fatal, "create socket error, errno code: %d, error string: %s\n", errno, strerror(errno));
            exit(Fatal);
        }
         lg.LogMessage(Debug, "create socket success, sockfd: %d\n", errno);
        // 2.初始化
        struct sockaddr_in local;
        memset(&local,sizeof(local),0);
        local.sin_family=AF_INET;
        local.sin_port=htons(_port);
        local.sin_addr.s_addr=htonl(INADDR_ANY);
       
       //2.1bind
        if (bind(_listensock, CONV(&local), sizeof(local)) != 0){
        lg.LogMessage(Fatal, "listen socket error, errno code: %d, error string: %s\n", errno, strerror(errno));
        exit(Bind_Err);
       }
       //3.设置socket为监听状态 tcp特有
         if (listen(_listensock, default_backlog) != 0)
        {
            lg.LogMessage(Fatal, "listen socket error, errno code: %d, error string: %s\n", errno, strerror(errno));
            exit(Listen_Err);
        }
        lg.LogMessage(Debug, "listen socket success, sockfd: %d\n", _listensock);
    
    }
    //全双工
    void Service(int sockfd)
    {
        char buffer[1024];
       while(true)
       {
           ssize_t n=read(sockfd,buffer,sizeof(buffer)-1);
           if(n>0){
            buffer[n]=0;
            cout<<"client say#"<<buffer<<endl;
            string echo_string = "sever echo#";
            echo_string +=buffer;
            write(sockfd,echo_string.c_str(),echo_string.size());
           }
             else if (n == 0) // read如果返回值是0，表示读到了文件结尾(对端关闭了连接！)
            {
                lg.LogMessage(Info, "client quit...\n");
                break;
            }
            else
            {
                lg.LogMessage(Error, "read socket error, errno code: %d, error string: %s\n", errno, strerror(errno));
                break;
            }
       }
    }
    void Start(){
         _isrunning =true;
         while(_isrunning ){
            //4.获取连接
            struct sockaddr_in peer;
            socklen_t len =sizeof(peer);
            int sockfd = accept(_listensock,CONV(&peer),&len);
            if(sockfd<0){
                lg.LogMessage(Warning, "accept socket error, errno code: %d, error string: %s\n", errno, strerror(errno));
                continue;
            }
             lg.LogMessage(Debug, "accept success, get n new sockfd: %d\n", sockfd);
             Service(sockfd);
             close(sockfd);
         }
    }


   ~TcpServer()
    {
    }

   private: 
    uint16_t _port;
    int _listensock;
    bool _isrunning;

};